﻿using System;
using System.Web.Mvc;
using System.Configuration;
using System.Collections.Generic;
using System.Linq;
using BoardPACDSWeb.Lang;
using BoardPACDSWeb.Models.General;
using System.ServiceModel;
using BoardPACDSBO.DownloadApp;
using BoardPACDSWeb.AnonymousUserServiceReference;
using BoardPACDSWeb.AuthorizeServiceReference;

namespace BoardPACDSWeb.Controllers
{
    public class DefaultController : BaseController
    {
        public static string ProductVersion = ConfigurationManager.AppSettings["AppVersion"].ToString();
        public static string Ip = ConfigurationManager.AppSettings["IP"].ToString();
        public static string pListPathDownload = ConfigurationManager.AppSettings["PListPathDownload"].ToString();
        public static string pListPathDeviceId = ConfigurationManager.AppSettings["PListPathDeviceId"].ToString();

        [Authorize]
        public ActionResult Index(string fmt)
        {
            try
            {
                char[] arr1 = { '(', ' ' };
                char[] arr2 = { '.' };
                char[] arr3 = { '_' };

                string tempVer = "";
                string minIOSVersion = ConfigurationManager.AppSettings["Min_IOS_Version"];
                string[] platform = Request.UserAgent.Split(arr1[0]);

                if (platform[1].Split(arr1[1])[0].Trim() != "iPad;")
                {
                    GenException exTemp = new GenException("err", "Please use an iPad device to login to this site.");
                    ModelState.AddModelError("err", exTemp);
                }

                string[] arrX = { "OS" };
                tempVer = platform[1].Split(arrX, StringSplitOptions.None)[1].Trim();
                tempVer = tempVer.Split(arr1[1])[0].Trim();

                int orgiOSVersion = getOSVersion(tempVer, arr3);
                int iOSVersionMin = getOSVersion(minIOSVersion, arr2);

                if (!(orgiOSVersion >= iOSVersionMin) && orgiOSVersion != 0 && iOSVersionMin != 0)
                {
                    GenException exTemp = new GenException("err", "Your iOS version " + tempVer.Replace("_", ".") + " is failed to meet the minimum supporting iOS version " +
                        minIOSVersion + ". " + Resources.Please_update_your_iPad_OS_);
                    ModelState.AddModelError("err", exTemp);
                }
            }
            catch (Exception e)
            {
                EventLog.Info("882, " + "ERR, " + EventStatus.Failure.ToString() + ", Default" + ", Index, " + User.Identity.Name + ", " + Resources.err_882);
                ErrorLog.Error("882, " + "ERR, " + EventStatus.Failure.ToString() + ", Default" + ", Index, " + User.Identity.Name + ", " + e.Message + ", " + e.InnerException);
                ModelState.AddModelError("err", new GenException("err_882"));
            }
            return GetFormatView("Home/Home.aspx");
        }

        /// <summary>
        /// Action to send the hosted iPa file version
        /// </summary>
        /// <param name="fmt">XML/HTML</param>
        /// <returns></returns>
        public ActionResult GetHostedVersion(string fmt)
        {
            string deviceId = Request.Headers.GetValues("X-deviceId") != null ? Request.Headers.GetValues("X-deviceId")[0] : null;
            string macAddress = Request.Headers.GetValues("X-macAddress") != null ? Request.Headers.GetValues("X-macAddress")[0] : null;

            EventLog.Info("0, " + "EVT, " + EventStatus.Entry.ToString() + ", Default" + ", GetHostedVersion, " + User.Identity.Name + ", [Parameters=(Parameter List: MAC Address" + macAddress + ". New version of BoardPAC download in progress)]");
            try
            {
                IsDeviceAllowed(deviceId, macAddress);

                ViewData["ProductVersion"] = GetProductVersion();
                ViewData["SupportInfo"] = pListPathDownload;

                EventLog.Info("0, " + "EVT, " + EventStatus.Success.ToString() + ", Default" + ", GetHostedVersion, " + User.Identity.Name + ", Successfully downloaded new upgrade.");
                Logs.WriteLogToDb("0, " + "EVT, " + EventStatus.Success.ToString() + ", Default" + ", GetHostedVersion, " + User.Identity.Name + ", Successfully downloaded new upgrade.");
            }
            catch (FaultException<BoardPACDSWeb.AnonymousUserServiceReference.GenFault> e)
            {
                ModelState.AddModelError("err", new GenException(e.Detail.Code));
            }
            catch (FaultException e)
            {
                ModelState.AddModelError("err", new GenException("err_881"));
            }
            catch (GenException e)
            {
                EventLog.Info(String.Format(Resources.log_err_0_InitDeviceXml, EventStatus.Failure.ToString(), e.Message));
                Logs.WriteLogToDb(String.Format(Resources.log_err_0_InitDeviceXml, EventStatus.Failure.ToString(), e.Message + " ," + e.InnerException + ", Stack Trace: " + e.StackTrace));
                ModelState.AddModelError("err", e);
            }
            catch (Exception e)
            {
                EventLog.Info("881, " + "ERR, " + EventStatus.Failure.ToString() + ", Default" + ", GetHostedVersion, " + User.Identity.Name + ", " + Resources.err_881);
                ErrorLog.Error("881, " + "ERR, " + EventStatus.Failure.ToString() + ", Default" + ", GetHostedVersion, " + User.Identity.Name + ", " + e.Message + ", " + e.InnerException);
                ModelState.AddModelError("err", new GenException("err_881"));
            }
            return GetFormatView("Home/GetHostedVersion.aspx");
        }

        [NonAction]
        public static string GetProductVersion()
        {
            return ProductVersion;
        }

        [NonAction]
        public static string GetWebAppIp()
        {
            return Ip;
        }

        [NonAction]
        public static string GetPListPathDownload()
        {
            return pListPathDownload;
        }

        [NonAction]
        public static string GetPListPathDeviceId()
        {
            return pListPathDeviceId;
        }

        internal void IsDeviceAllowed(string deviceId, string macAddress)
        {
            byte? result = null;
            try
            {
                using (AnonymousUserServiceClient anoClient = new AnonymousUserServiceClient())
                {
                    result = anoClient.GetIsDeviceAllowed(deviceId, macAddress);
                }
            }
            catch (Exception e)
            {
                throw;
            }

            #region moved to dao
            /*if (deviceId != null || macAddress != null)
            {
                using (BoardAppProductEntities entities = DataObjectFactory.CreateContext())
                {
                    Device device = null;

                    if (deviceId != null)
                    {
                        device = (from ud in entities.Devices
                                  where (ud.DeviceId.Equals(deviceId.Trim()))
                                  select ud).FirstOrDefault();
                    }

                    if (macAddress != null && device == null)
                    {
                        device = (from ud in entities.Devices
                                  where (ud.MacAddress.Equals(macAddress.Trim()))
                                  select ud).FirstOrDefault();
                    }

                    if (device == null) // Not registered yet.
                        throw new GenException("err_152");

                    if (device.Status == (byte)DeviceStatus.Wipeout) // device is in wipeout status
                        throw new GenException("err_155");

                    if (device.Status != (byte)DeviceStatus.Active) // device is in deactivate status
                        throw new GenException("err_153");
                }
            }
            else
            {
                throw new GenException("err_151");
            }*/
            
            #endregion
        }

        /// <summary>
        /// Action to send the hosted iPa file version
        /// </summary>
        /// <param name="fmt">XML/HTML</param>
        /// <returns></returns>
        [Authorize]
        public ActionResult UpdateDB(string iPaVersion, string dbVersion)
        {
            EventLog.Info("0, " + "EVT, " + EventStatus.Entry.ToString() + ", Default" + ", UpdaeteDB, " + User.Identity.Name + ", [Parameters=(Parameter List: iPaVersion = " + iPaVersion + ", dbVersion = " + dbVersion + ")]");
            DownloadAppModel downloadModel = new DownloadAppModel();

            try
            {
                using (AuthorizeClient authClient = new AuthorizeClient())
                {
                    SetCredentials(authClient);
                    downloadModel = authClient.UpdateDB(iPaVersion, dbVersion, GetLoggedUserId());
                }

                ViewData["iPaVersion"] = downloadModel.iPaVersion;
                ViewData["dbVersion"] = downloadModel.dbVersion;
                ViewData["UserName"] = downloadModel.Username;

                switch (downloadModel.MessageCode)
                {
                    case 1:
                        ViewData["Message"] = Resources.info_ipaVersionDBVersionIssue;
                        break;
                    case 2:
                        ViewData["Message"] = Resources.info_ipaVersionOutOfDateMsg;
                        break;
                    case 3:
                        ViewData["Message"] = Resources.info_dbVersionUptodateMsg;
                        break;
                }

                if (downloadModel.iPadDBScripts != null) 
                {
                    if (downloadModel.iPadDBScripts.Any())
                    {
                        return GetFormatView("Home/UpdateDB.aspx", downloadModel.iPadDBScripts);
                    }
                }
                    

                #region moved to dao
                /*using (BoardAppProductEntities entities = DataObjectFactory.CreateContext())
                {

                    if (iPaVersion == null)
                    {
                        throw new GenException("err_881");
                    }

                    if (dbVersion == null)
                    {
                        throw new GenException("err_883");
                    }

                    ViewData["iPaVersion"] = iPaVersion;
                    ViewData["dbVersion"] = dbVersion;

                    List<iPadDB> iPadDBScripts = new List<iPadDB>();
                    List<iPadDB> iPadDBAllScripts = (from i in entities.iPadDBs
                                                     select i).ToList();

                    List<string> Versions = (from i in iPadDBAllScripts
                                             select i.Version).Distinct().ToList();


                    int minScriptNumber = 0;
                    if (!Versions.Exists(i => i == dbVersion))
                    {
                        dbVersion = GetMinExistingVersion(dbVersion, Versions);
                    }

                    if (!string.IsNullOrWhiteSpace(dbVersion))
                    {
                        minScriptNumber = (from x in iPadDBAllScripts
                                           where x.Version.Equals(dbVersion)
                                           select x.ScriptOrder).Min();

                        int maxScriptNumber = 0;
                        if (!Versions.Exists(i => i == iPaVersion))
                        {
                            iPaVersion = GetMaxExistingVersion(iPaVersion, Versions);
                        }
                        if (!string.IsNullOrWhiteSpace(iPaVersion))
                        {
                            maxScriptNumber = (from x in iPadDBAllScripts
                                               where x.Version.Equals(iPaVersion)
                                               select x.ScriptOrder).Max();

                            if (maxScriptNumber >= minScriptNumber)
                            {
                                iPadDBScripts = (from i in entities.iPadDBs
                                                 where i.ScriptOrder <= maxScriptNumber && i.ScriptOrder >= minScriptNumber
                                                 orderby i.ScriptOrder
                                                 select i).ToList();
                            }
                            else
                            {
                                ViewData["Message"] = Resources.info_ipaVersionDBVersionIssue;
                            }

                        }
                        else
                        {
                            ViewData["Message"] = Resources.info_ipaVersionOutOfDateMsg;
                        }

                    }
                    else
                    {
                        ViewData["Message"] = Resources.info_dbVersionUptodateMsg;
                    }

                    int customUserId = GetLoggedUserId();
                    User user = (from u in entities.Users
                                 where u.CustomUserId == customUserId
                                 select u).FirstOrDefault();

                    ViewData["UserName"] = user.UserName;


                    EventLog.Info("0, " + "EVT, " + EventStatus.Success.ToString() + ", Default" + ", UpdaeteDB, " + User.Identity.Name + ", Successfully retrived the iPad DB changes.");

                    return GetFormatView("Home/UpdateDB.aspx", iPadDBScripts);
                }*/

                #endregion
            }
            catch (FaultException<BoardPACDSWeb.AuthorizeServiceReference.GenFault> e)
            {
                ModelState.AddModelError("err", new GenException(e.Detail.Code));
            }
            catch (FaultException e)
            {
                ModelState.AddModelError("err", new GenException("err_884"));
            }
            catch (GenException e)
            {
                ModelState.AddModelError("err", e);
            }
            catch (Exception e)
            {
                EventLog.Info("884, " + "ERR, " + EventStatus.Failure.ToString() + ", Default" + ", UpdaeteDB, " + User.Identity.Name + ", " + e.Message);
                ErrorLog.Error("884, " + "ERR, " + EventStatus.Failure.ToString() + ", Default" + ", UpdaeteDB, " + User.Identity.Name + ", " + e.Message + ", " + e.InnerException);
                ModelState.AddModelError("err", new GenException("err_884"));
            }
            return GetFormatView("Home/UpdateDB.aspx");
        }
        

        /// <summary>
        /// OS version converter to an integer
        /// </summary>
        /// <param name="iOsVersion">String version</param>
        /// <param name="arr">Splitter need to apply to the iOsVersion</param>
        /// <returns>Integer number of the version</returns>
        [NonAction]
        private int getOSVersion(string iOsVersion, char[] arr)
        {
            try
            {
                string[] verArr = iOsVersion.Split(arr);
                int vPart1 = int.Parse(verArr[0].Trim());
                int vPart2 = int.Parse(verArr[1].Trim());
                int vPart3 = int.Parse(verArr[2].Trim());
                int orgiOSVersion = int.Parse(vPart1 + "" + vPart2 + "" + vPart3);
                return orgiOSVersion;
            }
            catch (Exception)
            {
                return 0;
            }
        }
    }
}
